#include "utils.h"
#include <stdlib.h>
#include <sys/prctl.h>
#include <memory>

void StartDaemonProcess(string process_name)
{
    int fd = -1;
    int status;
    char cmdline[64];
    char buffer[2048];
    memset(buffer, 0, sizeof(buffer));

    if(0 == fork())
    {
        // 设置子进程名称为process_name
        prctl(PR_SET_NAME, process_name.data(), NULL, NULL, NULL);

        // 设置所有相关的fd，当执行新的程序后，相关的文件描述符都关闭
        sprintf(cmdline, "ls /proc/%d/fdinfo", getpid());
        FILE* fp = popen(cmdline, "r");
        while(fgets(buffer, sizeof(buffer), fp))
        {
            fd = atoi(buffer);
            if(fd > 2)
            {
                int val = fcntl(fd, F_GETFD);
                val |= FD_CLOEXEC;
                fcntl(fd, F_SETFD, val);
            }
        }
        pclose(fp);

        // 将进程编程守护进程
        daemon(1, 0);
        printf("process %s starting, pid=%d\n", process_name.data(), getpid());

        // sprintf(cmdline, "/opt/mt/ctl/%s &", apisrvname.data());
        // system(cmdline);
        char* ps_argv[2];
        char* ps_envp[2];
        ps_argv[0] = (char*)process_name.data();
        ps_argv[1] = NULL;

        // 设置当前目录到环境变量
        char envPath[512];
        sprintf(envPath, "%s:%s", getenv("PATH"), get_current_dir_name());
        setenv("PATH", envPath, 1);

        ps_envp[0] = envPath;
        ps_envp[1] = NULL;
        char curPath[128];
        sprintf(curPath, "%s/%s", get_current_dir_name(), process_name.data());
        // 启动新进程
        if(execvp(process_name.data(), (char* const*)ps_argv) < 0)
        {  
            printf("execvpe path=%s, proc name=%s, error=%d!\n", curPath, process_name.data(), errno);
        }
        else
        {
            printf("start process %s success!\n", process_name.data());
        }
        exit(-1);
    }
}

int KillProcess(string process_name)
{
    char cmd[128];
    sprintf(cmd, "kill -9 $(pgrep %s)", process_name.data());
    return system(cmd);
}

string exec(const char *cmd)
{
    std::array<char, 128> buffer;
    std::string result;
    std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
    if (!pipe) {
        throw std::runtime_error("popen() failed!");
    }
    while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
        result += buffer.data();
    }
    return result;
}

bool isProcessRunning(const char* processName) {
    // 构建命令字符串，使用pgrep查找进程名
    char command[128];
    snprintf(command, sizeof(command), "pgrep %s", processName);

    // 执行命令
    FILE* pipe = popen(command, "r");
    if (!pipe) {
        std::cerr << "popen failed!" << std::endl;
        return false;
    }

    // 读取命令输出
    char buffer[128];
    while (fgets(buffer, sizeof(buffer), pipe) != NULL) {
        // 如果pgrep找到了匹配的进程ID，说明进程存在
        if (strlen(buffer) > 0 && buffer[strlen(buffer)-1] == '\n') {
            buffer[strlen(buffer)-1] = '\0'; // 移除换行符
            int pid = atoi(buffer);
            if (pid > 0) {
                pclose(pipe);
                return true;
            }
        }
    }

    // 没有找到匹配的进程
    pclose(pipe);
    return false;
}

// int main()
// {
    // StartDaemonProcess("blueriver_control");
    // sleep(10);
    // KillProcess("blueriver_control");
    // const char* processName = "blueriver_control";
    // if (isProcessRunning(processName)) {
    //     std::cout << "The process " << processName << " is running." << std::endl;
    // } else {
    //     std::cout << "The process " << processName << " is not running." << std::endl;
    // }
//     return 0;
// }